package com.example.demo.base.readfile;

import org.junit.Test;

import java.io.*;
import java.util.*;
import java.util.concurrent.*;

/**
 * @program: java_base
 * @description: 读取文件，设想成netty模型
 * @author: zhouhongtao
 * @happyCreateTime: 2022/01/25 20:39
 */
public class ReadFiles {

    volatile int i = 0;


    @Test
    public void test20220125() throws InterruptedException {
        long start = System.currentTimeMillis();
        String path = "G:\\ebook";
        File file = new File(path);
        String[] arr = file.list();

        List<String> list = Arrays.asList(arr);

//        TreeBasedTable<Long, String, File> treeBasedTable = TreeBasedTable.create();
//        for (String s : arr) {
//            File file1 = new File(path+"\\"+s);
//            long length = file1.length();
//            treeBasedTable.put(length, s, file1);
//        }
//        SortedSet<Long> longs = treeBasedTable.rowKeySet();
//        SortedMap<Long, Map<String, File>> longMapSortedMap = treeBasedTable.rowMap();
//        System.out.println(longMapSortedMap.size());
//        System.out.println(fileSize.size());
//        System.out.println(treeBasedTable.size());
//        System.out.println(list.size());

        List<String> fileNames0 = list.subList(0, 2648);
        List<String> fileNames1 = list.subList(2648, 5296);
        List<String> fileNames2 = list.subList(5296, 7944);
        List<String> fileNames3 = list.subList(7944, 10592);
        List<String> fileNames4 = list.subList(10592, 13240);
        List<String> fileNames5 = list.subList(13240, 15888);
        List<String> fileNames6 = list.subList(15888, 18536);
        List<String> fileNames7 = list.subList(18536, 21186);

        List<List<String>> lists = new ArrayList<>();
        lists.add(fileNames0);
        lists.add(fileNames1);
        lists.add(fileNames2);
        lists.add(fileNames3);
        lists.add(fileNames4);
        lists.add(fileNames5);
        lists.add(fileNames6);
        lists.add(fileNames7);

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                8, 8, 60 * 20, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(16));

        CountDownLatch doneSignal = new CountDownLatch(8);

        for (int i = 0; i < 8; ++i) { // create and start threads
            threadPoolExecutor.execute(new ReadFileWorker(doneSignal, i, lists.get(i)));
        }
        doneSignal.await();           // wait for all to finish
        long end = System.currentTimeMillis();
        System.out.println("end - start 毫秒" + (end - start));
    }

}

class ReadFileWorker implements Runnable{
    String path = "G:\\ebook";

    private final CountDownLatch doneSignal;
    private final int i;
    private List<String> fileNames;
    ReadFileWorker(CountDownLatch doneSignal, int i, List<String> fileNames) {
        this.doneSignal = doneSignal;
        this.i = i;
        this.fileNames = fileNames;
    }

    public String doWork() {
        for (int j = 0; j < fileNames.size(); j++) {
            String fileNamePath = path +"\\" + fileNames.get(j);
           readFile(new File(fileNamePath));
        }
        return "";
    }

    /**
     * 将文件转换为string
     * @param file
     * @return
     */
    public String readFile(File file) {
        try {
            // 把每次读取的内容写入到内存中，然后从内存中获取
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] buffer = new byte[1024];
            int len = 0;
            // 只要没读完，不断的读取
            while ((len = fileInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
            // 得到内存中写入的所有数据
            byte[] data = outputStream.toByteArray();
            fileInputStream.close();
            return new String(data);
            //return new String(data, "GBK");//以GBK（什么编码格式）方式转
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    /**
     * When an object implementing interface {@code Runnable} is used
     * to create a thread, starting the thread causes the object's
     * {@code run} method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method {@code run} is that it may
     * take any action whatsoever.
     *
     * @see Thread#run()
     */
    @Override
    public void run() {
        System.out.println(i);
        String res = doWork();
        doneSignal.countDown();
    }
}

